home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 3 / Amiga Tools 3.iso / grafik / raytracing / rayshade-4.0.6.3 / raypaint / xgraphics.c < prev   
Encoding:
C/C++ Source or Header  |  1994-08-09  |  10.2 KB  |  385 lines

  1. /*
  2.  * xgraphics.c
  3.  *
  4.  * Copyright (C) 1989, 1991 Craig E. Kolb, Rod G. Bogart
  5.  *
  6.  * This software may be freely copied, modified, and redistributed
  7.  * provided that this copyright notice is preserved on all copies.
  8.  *
  9.  * You may not distribute this software, in whole or in part, as part of
  10.  * any commercial product without the express consent of the authors.
  11.  * 
  12.  * There is no warranty or other guarantee of fitness of this software
  13.  * for any purpose.  It is provided solely "as is".
  14.  *
  15.  * xgraphics.c,v 4.1 1994/08/09 08:06:31 explorer Exp
  16.  *
  17.  * xgraphics.c,v
  18.  * Revision 4.1  1994/08/09  08:06:31  explorer
  19.  * Bump version to 4.1
  20.  *
  21.  * Revision 1.1.1.1  1994/08/08  04:52:27  explorer
  22.  * Initial import.  This is a prerelease of 4.0.6enh3, or 4.1 possibly.
  23.  *
  24.  * Revision 4.0  91/07/17  17:37:32  kolb
  25.  * Initial version.
  26.  * 
  27.  */
  28.  
  29. #include <stdio.h>
  30. #include <math.h>
  31. #include <X11/Xlib.h>
  32. #include <X11/Xutil.h>
  33.  
  34. char *display_name = NULL;
  35. Display *dpy = NULL;
  36. Screen *scrn;
  37. Visual *vis;
  38. Colormap cmap;
  39. GC gc;
  40. Window win;
  41. int screen_height;
  42. int gray;
  43.  
  44. unsigned long colormap[256];
  45. int max_colors;
  46. double one_over_gamma = 0.4;
  47.  
  48. /*****************************************************************
  49.  * Sets the gray color map for the device.  A 2.5 gamma map is used
  50.  * by default.
  51.  */
  52. static
  53. setup_gray_gamma_map()
  54. {
  55.     int cc, col;
  56.     int gamma_color;
  57.  
  58.     XColor xcolor;
  59.  
  60.     gray = 1;
  61.     /* Use the default colormap if possible. */
  62.     if ( vis == DefaultVisualOfScreen( scrn ) )
  63.         cmap = DefaultColormapOfScreen( scrn );
  64.     else
  65.         cmap = XCreateColormap( dpy, RootWindowOfScreen( scrn ),
  66.                                vis, AllocNone );
  67.  
  68.     /* try to share with current colormap */
  69.     for (max_colors = 256; max_colors >= 16; max_colors = max_colors >> 1) {
  70.         xcolor.flags= DoRed | DoGreen | DoBlue;
  71.         for(col=0; col < max_colors; col++) {
  72.             gamma_color = (pow((float) col / (float) max_colors,
  73.                                one_over_gamma) * 65536);
  74.             xcolor.red= gamma_color;
  75.             xcolor.green= gamma_color;
  76.             xcolor.blue= gamma_color;
  77.             if (!XAllocColor(dpy, cmap, &xcolor)) {
  78.                 for (cc=0; cc < col; cc++)
  79.                     XFreeColors(dpy, cmap, &colormap[cc], 1, 0);
  80.                 col = 0;
  81.                 break;
  82.             }
  83.             colormap[col] = xcolor.pixel;
  84.         }
  85.         if (col)
  86.             return;
  87.     }
  88.  
  89.     /* use new map */
  90.     cmap = XCreateColormap( dpy, RootWindowOfScreen( scrn ),
  91.                            vis, AllocNone );
  92.     if (cmap == NULL)  {
  93.         fprintf(stderr, "Could not create color map for visual\n");
  94.         exit(-2);
  95.     }
  96.     for(cc=0; cc < 256; cc++)
  97.         if (!XAllocColorCells(dpy, cmap, False, NULL, 0, &colormap[cc], 1))
  98.             break;
  99.     max_colors = cc;
  100.  
  101.     xcolor.flags= DoRed | DoGreen | DoBlue;
  102.     for(col=0; col < max_colors; col++) {
  103.         xcolor.pixel= colormap[col];
  104.         gamma_color = (pow((float) col / (float) max_colors,
  105.                            one_over_gamma) * 65536);
  106.         xcolor.red= gamma_color;
  107.         xcolor.green= gamma_color;
  108.         xcolor.blue= gamma_color;
  109.         XStoreColor(dpy, cmap, &xcolor);
  110.     }
  111. }
  112.  
  113. /*****************************************************************
  114.  * Sets the color map for the device.  A 2.5 gamma map is used
  115.  * by default, with a direct 6x7x5 colormap
  116.  */
  117. static
  118. setup_color_gamma_map()
  119. {
  120.     static int first_try = 1;
  121.     int cc, col;
  122.     int r, g, b;
  123.     int done;
  124.  
  125.     XColor xcolor;
  126.  
  127.     /* Use the default colormap if possible. */
  128.     if (first_try && vis == DefaultVisualOfScreen(scrn)) {
  129.         cmap = DefaultColormapOfScreen(scrn);
  130.     } else {
  131.         cmap = XCreateColormap(dpy, RootWindowOfScreen(scrn),
  132.                                vis, AllocNone );
  133.     }
  134.  
  135.     /* try to share with current colormap */
  136.     xcolor.flags= DoRed | DoGreen | DoBlue;
  137.     for (max_colors = 6; max_colors >= 2; --max_colors) {
  138.     done = 1; /* gets unset on failure */
  139.     col = 0;
  140.     for (r = 0; r < max_colors; ++r) {
  141.         xcolor.red = pow((float) r / (float) max_colors,
  142.         one_over_gamma) * 65536;
  143.         for (g = 0; g < max_colors; ++g) {
  144.         xcolor.green = pow((float) g / (float) max_colors,
  145.             one_over_gamma) * 65536;
  146.         for (b = 0; b < max_colors; ++b) {
  147.             xcolor.blue = pow((float) b / (float) max_colors,
  148.                     one_over_gamma) * 65536;
  149.             if (!XAllocColor(dpy, cmap, &xcolor)) {
  150.             for (cc=0; cc < col; cc++)
  151.                 XFreeColors(dpy, cmap, &colormap[cc], 1, 0);
  152.             r = g = b = 99;
  153.                 done = 0;
  154.                 break;
  155.             }
  156.             colormap[col++] = xcolor.pixel;
  157.         }
  158.         }
  159.     }
  160.     if (done)
  161.         break;
  162.     }
  163.     if (!done) {
  164.     if (first_try) {
  165.         /* go back and try with a private color map */
  166.         first_try = 0;
  167.         setup_color_gamma_map();
  168.     }
  169.     /* our smallest color set (2x2x2 = 8) is smaller than the
  170.      * grayscale code (16), but we still try the gray map because
  171.      * it might be able to share colors.
  172.      */
  173.         fprintf(stderr, "Could not create color map -- trying grayscale\n");
  174.     setup_gray_gamma_map();
  175.     return;
  176.     }
  177.     fprintf(stderr, "using standard %dx%dx%d colormap\n", max_colors, max_colors, max_colors);
  178.     gray = 0;
  179. }
  180.  
  181. GraphicsInit(xsize, ysize, name, gray)
  182. int xsize, ysize;
  183. char *name;
  184. int gray;
  185. {
  186.     int win_size;
  187.     XSetWindowAttributes attrs;
  188.     XSizeHints sh;
  189.  
  190.     /* Open the display. */
  191.     if ( ! dpy )
  192.     {
  193.         XVisualInfo vis_temp, *vis_list, *max_vis;
  194.         int n_ret, i;
  195.  
  196.         dpy = XOpenDisplay( display_name );
  197.         if ( ! dpy )
  198.         {
  199.             fprintf( stderr, "rayview: Can't open display %s\n",
  200.                      XDisplayName( display_name ) );
  201.             exit(1);
  202.         }
  203.  
  204.         /* Get a PseudoColor visual that has the maximum number of planes. */
  205.         vis_temp.class = PseudoColor;
  206.         vis_list = XGetVisualInfo( dpy, VisualClassMask, &vis_temp, &n_ret );
  207.         if ( n_ret == 0 )
  208.         {
  209.             fprintf(stderr,
  210.                     "Can't find any PseudoColor visual from display %s.\n",
  211.                     XDisplayName( display_name ));
  212.             exit(1);
  213.         }
  214.         max_vis = &vis_list[0];
  215.         for ( i = 1; i < n_ret; i++ )
  216.         {
  217.             if ( max_vis->depth < vis_list[i].depth )
  218.                 max_vis = &vis_list[i];
  219.         }
  220.         vis = max_vis->visual;
  221.         scrn = ScreenOfDisplay( dpy, max_vis->screen );
  222.         gc = DefaultGCOfScreen( scrn );
  223.  
  224.     if (gray) {
  225.         setup_gray_gamma_map();
  226.     } else {
  227.             setup_color_gamma_map();
  228.     }
  229.  
  230.         XFree( (char *)vis_list );
  231.     }
  232.  
  233.     screen_height = ysize;
  234.  
  235.     attrs.backing_store = Always;
  236.     attrs.colormap = cmap;
  237.     attrs.event_mask = ExposureMask;
  238.     attrs.background_pixel = BlackPixelOfScreen(scrn);
  239.     attrs.border_pixel = WhitePixelOfScreen(scrn);
  240.  
  241.     win = XCreateWindow( dpy, RootWindowOfScreen( scrn ),
  242.                          0, 0, xsize, ysize, 2,
  243.                          0, 0, vis,
  244.                          CWBackingStore | CWColormap | CWEventMask |
  245.                          CWBackPixel | CWBorderPixel,
  246.                          &attrs );
  247.  
  248.     sh.flags = PSize | PMinSize | PMaxSize;
  249.     sh.width = sh.min_width = sh.max_width = xsize;
  250.     sh.height = sh.min_height = sh.max_height = ysize;
  251.     XSetStandardProperties( dpy, win, name, name, None, NULL, 0, &sh );
  252.  
  253.     XMapWindow( dpy, win );
  254.  
  255.     XFlush( dpy );
  256. }
  257.  
  258. /*
  259.  * Draw the pixel at (xp, yp) in the color given by the rgb-triple,
  260.  * 0 indicating 0 intensity, 255 max intensity.
  261.  */
  262. GraphicsDrawPixel(xp, yp, color)
  263. int xp, yp;
  264. unsigned char color[3];
  265. {
  266.     int val;
  267.  
  268.     if (gray) {
  269.     val = (0.35*color[0] + 0.55*color[1] + 0.10*color[2]) / 256.0 * max_colors;
  270.     } else {
  271.     val = color[0] / 256.0 * max_colors;
  272.     val *= max_colors;
  273.     val += color[1] / 256.0 * max_colors;
  274.     val *= max_colors;
  275.     val += color[2] / 256.0 * max_colors;
  276.     }
  277.     XSetForeground( dpy, gc, colormap[val] );
  278.     XFillRectangle( dpy, win, gc, xp, (screen_height - (yp + 1)),
  279.                     1, 1 );
  280. }
  281.  
  282. /*
  283.  * Draw the rect with lower left corner (xp, yp) and upper right
  284.  * corner (xp+ys, yp+ys).  The colors of the l-l, l-r, u-r, and u-l
  285.  * corners are given as arrays of unsigned chars as above.
  286.  */
  287. GraphicsDrawRectangle(xp, yp, xs, ys, ll, lr, ur, ul)
  288. int xp, yp, xs, ys;
  289. unsigned char ll[3], lr[3], ur[3], ul[3];
  290. {
  291.     int val;
  292.  
  293.     ll[0] = (ll[0] + lr[0] + ur[0] + ul[0]) / 4;
  294.     ll[1] = (ll[1] + lr[1] + ur[1] + ul[1]) / 4;
  295.     ll[2] = (ll[2] + lr[2] + ur[2] + ul[2]) / 4;
  296.     if (gray) {
  297.     val = (0.35*ll[0] + 0.55*ll[1] + 0.10*ll[2]) / 256.0 * max_colors;
  298.     } else {
  299.     val = ll[0] / 256.0 * max_colors;
  300.     val *= max_colors;
  301.     val += ll[1] / 256.0 * max_colors;
  302.     val *= max_colors;
  303.     val += ll[2] / 256.0 * max_colors;
  304.     }
  305.     XSetForeground( dpy, gc, colormap[val] );
  306.     XFillRectangle( dpy, win, gc, xp, (screen_height - (yp + ys + 1)),
  307.                     xs+1, ys+1 );
  308.     XFlush( dpy );
  309. }
  310.  
  311. GraphicsLeftMouseEvent()
  312. {
  313.     Window root_ret, child_ret;
  314.     int rx, ry, wx, wy;
  315.     unsigned int mask;
  316.  
  317.     if (XQueryPointer(dpy, win, &root_ret, &child_ret,
  318.                       &rx, &ry, &wx, &wy, &mask)) {
  319.         return mask & Button1Mask;
  320.     }
  321.     else
  322.         return 0;
  323. }
  324.  
  325. GraphicsMiddleMouseEvent()
  326. {
  327.     Window root_ret, child_ret;
  328.     int rx, ry, wx, wy;
  329.     unsigned int mask;
  330.  
  331.     if (XQueryPointer(dpy, win, &root_ret, &child_ret,
  332.                       &rx, &ry, &wx, &wy, &mask)) {
  333.         return mask & Button2Mask;
  334.     }
  335.     else
  336.         return 0;
  337. }
  338.  
  339. GraphicsRightMouseEvent()
  340. {
  341.     Window root_ret, child_ret;
  342.     int rx, ry, wx, wy;
  343.     unsigned int mask;
  344.  
  345.     if (XQueryPointer(dpy, win, &root_ret, &child_ret,
  346.                       &rx, &ry, &wx, &wy, &mask)) {
  347.         return mask & Button3Mask;
  348.     }
  349.     else
  350.         return 0;
  351. }
  352.  
  353. GraphicsGetMousePos(x, y)
  354. int *x, *y;
  355. {
  356.     Window root_ret, child_ret;
  357.     int rx, ry, wx, wy;
  358.     unsigned int mask;
  359.  
  360.     if (XQueryPointer(dpy, win, &root_ret, &child_ret,
  361.                       &rx, &ry, &wx, &wy, &mask)) {
  362.         *x = wx;
  363.         *y = screen_height - wy - 1;
  364.     }
  365.     else {
  366.         *x = 0;
  367.         *y = 0;
  368.     }
  369. }
  370.  
  371. GraphicsRedraw()
  372. {
  373.         XEvent event;
  374.         if (XCheckTypedEvent(dpy, Expose, &event)) {
  375.                 XSetForeground( dpy, gc, colormap[0] );
  376.                 XFillRectangle( dpy, win, gc, event.xexpose.x, event.xexpose.y,
  377.                     event.xexpose.width, event.xexpose.height );
  378.                 XFlush( dpy );
  379.                 return 1;
  380.         }
  381.         else
  382.                 return 0;
  383. }
  384.  
  385.